﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

//namespace Model.ColaPrioridad
namespace Model
{
    public class ColaPrioridad : IColaPrioridad
    {


        // -----------------------------------------------------------------
        // Atributos
        // -----------------------------------------------------------------
        /**
        * Primer elemento de la cola encadenada
        */
        public NodoColaPrioridad primero;

        /**
        * Ultimo elemento de la cola encadenada
        */
        public NodoColaPrioridad ultimo;

        /**
        * Número de elementos de la cola
        */
        public int numeroPacientes;


        // -----------------------------------------------------------------
        // Constructores
        // -----------------------------------------------------------------
        /**
        * Constructor de la cola encadenada vacía. <br>
        * <b>post: </b> Se construyó una cola vacía. primero==null, ultimo==null, numElems = 0<br>
        */
        public ColaPrioridad()
        {
            primero = null;
            ultimo = null;
            numeroPacientes = 0;
        }


        public void encolar(int prioridad, Paciente paciente)
        {
            NodoColaPrioridad nodo = new NodoColaPrioridad(prioridad, paciente);
            if (primero == null)
            {
                primero = nodo;
                ultimo = nodo;
            }
            // Verifica si tiene mayor prioridad que el primer elemento de la cola
            else if (primero.darPrioridad()-(prioridad) > 0)
            {
                //validar si el triage es 1 se pone siempre de primero sino, mirar que si el que esta antes no lleva mucho tiempo esperando
                if (prioridad == 1)
                {
                    nodo.insertarDespues(primero);
                    primero = nodo;
                }
                else
                {
                    Paciente p = primero.darPaciente();
                    string tiempoEspera = p.historial.calcularTiempoEspera();
                    string[] horasMinutos = tiempoEspera.Split(':');
                    int hora = int.Parse(horasMinutos[0]);
                    int minutos = int.Parse(horasMinutos[1]);

                    switch (primero.darPrioridad())
                        {
                            case 3:

                                if (hora == 0 && minutos < 40)
                                {
                                    nodo.insertarDespues(primero);
                                    primero = nodo;
                                }
                                else
                                {
                                    nodo.insertarDespues(primero.darSiguiente());
                                    primero.insertarDespues(nodo);
                                }
                                break;

                             case 4:
                                if (hora < 3)
                                {
                                    nodo.insertarDespues(primero);
                                    primero = nodo;
                                }
                                else
                                {
                                    nodo.insertarDespues(primero.darSiguiente());
                                    primero.insertarDespues(nodo);
                                }
                                break;
                        }                    
                }
            }
            else
            {
                // Recorre la cola hasta encontrar un nodo de menor prioridad
                bool inserto = false;
                for (NodoColaPrioridad p = primero; !inserto && p.darSiguiente() != null; p = p.darSiguiente())
                {
                    if (p.darSiguiente().darPrioridad()-(prioridad) > 0)
                    {
                        //mirar que si el que esta antes no lleva mucho tiempo esperando

                        Paciente pa = p.darSiguiente().darPaciente();
                        string tiempoEspera = pa.historial.calcularTiempoEspera();
                        string[] horasMinutos = tiempoEspera.Split(':');
                        int hora = int.Parse(horasMinutos[0]);
                        int minutos = int.Parse(horasMinutos[1]);

                        switch (p.darSiguiente().darPrioridad())
                        {
                            case 3:

                                if (hora == 0 && minutos < 40)
                                {
                                    nodo.insertarDespues(p.darSiguiente());
                                    p.insertarDespues(nodo);
                                    inserto = true;
                                }
                                else
                                {
                                    nodo.insertarDespues(p.darSiguiente().darSiguiente());
                                    p.darSiguiente().insertarDespues(nodo);
                                }
                                break;

                            case 4:
                                if (hora < 3)
                                {
                                    nodo.insertarDespues(p.darSiguiente());
                                    p.insertarDespues(nodo);
                                    inserto = true;
                                }
                                else
                                {
                                    nodo.insertarDespues(p.darSiguiente().darSiguiente());
                                    p.darSiguiente().insertarDespues(nodo);
                                }
                                break;
                        }

                    }
                }
                if (!inserto)
                {
                    // No lo ha insertado porque tiene la menor prioridad de toda la cola
                    ultimo = ultimo.insertarDespues(nodo);
                }
            }
            numeroPacientes++;
        }

        /**
         * Retorna el primer elemento y lo elimina de la cola. <br>
         * <b>post: </b> Se retornó y eliminó el primer elemento de la cola. Si es el único elemento, el primero y el ultimo son null. La cantidad de los elementos se reduce en 1<br>
         * @return El primer elemento de la cola. Diferente de null<br>
         * @throws ColaVaciaException Si la cola no tiene elementos<br>
*/
        public Paciente tomarElemento()
        {
            if (primero == null)
                return null;
            else
            {
                NodoColaPrioridad p = primero;
                primero = primero.desconectarPrimero();
                if (primero == null)
                    ultimo = null;
                numeroPacientes--;
                return p.darPaciente();
            }
        }

        // -----------------------------------------------------------------
        // Métodos
        // -----------------------------------------------------------------
        /**
        * Retorna la longitud de la cola (número de elementos). <br>
        * <b>post: </b> Se retornó la longitud de la cola<br>.
        * @return El número de elementos de la cola. Entero positivo o cero.<br>
        */
        public int darLongitud()
        {
            return numeroPacientes;
        }

        public NodoColaPrioridad darPrimero()
        {
            return primero;
        }

        public NodoColaPrioridad darUltimo()
        {
            return ultimo;
        }

        public bool estaVacia()
        {
            return primero == null;
        }
    }
}
